package com.caregiver.watch.common.helper;

import com.caregiver.watch.common.constant.Constants;
import com.caregiver.watch.common.utils.spring.SpringUtils;
import com.caregiver.watch.common.utils.time.DateUtils;
import org.springframework.data.redis.core.RedisTemplate;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static com.caregiver.watch.common.utils.time.DateUtils.YYYYMMDD;
import static com.caregiver.watch.common.utils.time.DateUtils.YYYYMMDDHHMM;

/**
 * @Description: 顺序单号生成器
 * @Author 疆戟
 * @Date 2024/3/22 21:05
 * @Version 1.0
 */
public final class SequentialNoHelper {

    private static final String SEQUENTIAL_NUMBER_GENERATOR = "SEQUENTIAL_NUMBER_GENERATOR";

    private static volatile RedisTemplate redisTemplate;

    /**
     * 生成订单号
     *
     * @param prefix
     * @param userId
     * @return
     */
    public static String generateNo(String prefix, Long userId) {
        RedisTemplate redis = getRedis();
        // 获取当前时间
        LocalDateTime currentTime = LocalDateTime.now();
        final String key = SEQUENTIAL_NUMBER_GENERATOR +
                Constants.COLON + userId +
                Constants.COLON + DateUtils.format(currentTime.toLocalDate(), YYYYMMDD);
        if (!redis.hasKey(key)) {
            // 获取明天凌晨0点时间
            LocalDateTime tomorrowMidnight = LocalDateTime.of(currentTime.toLocalDate().plusDays(1), LocalTime.MIDNIGHT);
            // 计算当前时间到明天凌晨0点的小时差
            long hoursUntilTomorrow = ChronoUnit.HOURS.between(currentTime, tomorrowMidnight);
            // 如果不存在设置一个超时
            redis.opsForValue().set(key, 0, hoursUntilTomorrow + 1, TimeUnit.HOURS);
        }
        // 生成一个随机的3位数
        long randomNumber = (long) (Math.random() * 1000);
        //自增序列
        Long increment = redis.opsForValue().increment(key, randomNumber);
        return prefix +
                String.format("%07d", userId) +
                DateUtils.format(currentTime, YYYYMMDDHHMM) +
                String.format("%03d", increment.intValue());
    }

    /**
     * 获取RedisTemplate
     *
     * @return
     */
    private static RedisTemplate getRedis() {
        if (Objects.nonNull(redisTemplate)) {
            return redisTemplate;
        }
        synchronized (SequentialNoHelper.class) {
            if (Objects.nonNull(redisTemplate)) {
                return redisTemplate;
            }
            redisTemplate = SpringUtils.getBean("redisTemplate");
        }
        return redisTemplate;
    }
}
